/*-------------------------------------------------------------------------
 *
 * dict.c
 *		标准字典接口
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 *
 *
 * IDENTIFICATION
 *	  src/backend/tsearch/dict.c
 *
 *-------------------------------------------------------------------------
 */
#include "postgres.h"

#include "catalog/pg_type.h"
#include "tsearch/ts_cache.h"
#include "tsearch/ts_utils.h"
#include "utils/builtins.h"


/*
 * 根据词典对一个单词进行词汇化，主要是调试功能
 */
Datum ts_lexize(PG_FUNCTION_ARGS)
{
	Oid			fc_dictId = PG_GETARG_OID(0);
	text	   *fc_in = PG_GETARG_TEXT_PP(1);
	ArrayType  *fc_a;
	TSDictionaryCacheEntry *fc_dict;
	TSLexeme   *fc_res,
			   *fc_ptr;
	Datum	   *fc_da;
	DictSubState fc_dstate = {false, false, NULL};

	fc_dict = lookup_ts_dictionary_cache(fc_dictId);

	fc_res = (TSLexeme *) DatumGetPointer(FunctionCall4(&fc_dict->lexize,
													 PointerGetDatum(fc_dict->dictData),
													 PointerGetDatum(VARDATA_ANY(fc_in)),
													 Int32GetDatum(VARSIZE_ANY_EXHDR(fc_in)),
													 PointerGetDatum(&fc_dstate)));

	if (fc_dstate.getnext)
	{
		fc_dstate.isend = true;
		fc_ptr = (TSLexeme *) DatumGetPointer(FunctionCall4(&fc_dict->lexize,
														 PointerGetDatum(fc_dict->dictData),
														 PointerGetDatum(VARDATA_ANY(fc_in)),
														 Int32GetDatum(VARSIZE_ANY_EXHDR(fc_in)),
														 PointerGetDatum(&fc_dstate)));
		if (fc_ptr != NULL)
			fc_res = fc_ptr;
	}

	if (!fc_res)
		PG_RETURN_NULL();

	fc_ptr = fc_res;
	while (fc_ptr->lexeme)
		fc_ptr++;
	fc_da = (Datum *) palloc(sizeof(Datum) * (fc_ptr - fc_res));
	fc_ptr = fc_res;
	while (fc_ptr->lexeme)
	{
		fc_da[fc_ptr - fc_res] = CStringGetTextDatum(fc_ptr->lexeme);
		fc_ptr++;
	}

	fc_a = construct_array(fc_da,
						fc_ptr - fc_res,
						TEXTOID,
						-1,
						false,
						TYPALIGN_INT);

	fc_ptr = fc_res;
	while (fc_ptr->lexeme)
	{
		pfree(DatumGetPointer(fc_da[fc_ptr - fc_res]));
		pfree(fc_ptr->lexeme);
		fc_ptr++;
	}
	pfree(fc_res);
	pfree(fc_da);

	PG_RETURN_POINTER(fc_a);
}
